package com.jiankang.askhealth.util;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;


public class StringUtils extends org.apache.commons.lang.StringUtils{
    private static final String PASSWORD_CRYPT_KEY = "__tour__";
	private final static String DES = "DES";

    private static Pattern saveTagImgPattern = Pattern.compile("<\\s*(img)([^>]*)/?>");
    private static Pattern saveTagHolderPattern = Pattern.compile("!@!");
    private static Pattern htmlTagPattern = Pattern.compile("(?m)(\\<.*?\\>)*(\\&.*?\\;)*");
    private static Pattern imgTagPattern = Pattern.compile("(?m)<img\\s+[^>]*>");
    private static Pattern wideSpacePattern = Pattern.compile("(?m)　");
    private static Pattern lineBreakPattern = Pattern.compile("[\\r|\\n]");
    private static Pattern quoteMarkPattern = Pattern.compile("(?m)[\"]");
    private static Pattern lineBreakTagPattern = Pattern.compile("<br/>");
    private static Pattern lineBreakConvertPattern = Pattern.compile("\\r\\n");
    private static Pattern commentQuotePattern = Pattern.compile("(?m)<div\\s+class=hide>=+<\\/div>");
    private static Pattern commentQuoteContentPattern = Pattern.compile("(?m)<div\\s+class=quote-content>.*<\\/div>");
    private static Pattern hyperPlaceLinkTagBugFixPattern1 = Pattern.compile("<a\\s[^>]*?class=\"hyper\"[^>]*?>[^>]*?</a>自助游\">");
    private static Pattern hyperPlaceLinkTagBugFixPattern2 = Pattern.compile("<a\\s[^>]*?class=\"hyper\"[^>]*?>[^>]*?</a>自助游&quot;&gt;");
    private static Pattern hyperPlaceLinkTagPattern = Pattern.compile("<a\\s[^>]*class=\"hyper\"[^>]*>(.*?)</a>");
    private static Pattern linkTagPattern1 = Pattern.compile("<a\\s+[^>]*href[^>]*>");
    private static Pattern linkTagPattern2 = Pattern.compile("<\\s*/\\s*a\\s*>");
    private static Pattern emailPattern = Pattern.compile("[\\w\\-]+(\\.[\\w\\-]+)*@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}");
    private static Pattern phonePattern = Pattern.compile("\\(?([0-9１２３４５６７８９０－一二三四五六七八九零壹贰叁肆伍陆柒捌玖①②③④⑤⑥⑦⑧⑨㈠㈡㈢㈣㈤㈥㈦㈧㈨⑴⑵⑶⑷⑸⑹⑺⑻⑼⒈⒉⒊⒋⒌⒍⒎⒏⒐\\s]{2,4})\\)?[- ]?([0-9１２３４５６７８９０－一二三四五六七八九零壹贰叁肆伍陆柒捌玖①②③④⑤⑥⑦⑧⑨㈠㈡㈢㈣㈤㈥㈦㈧㈨⑴⑵⑶⑷⑸⑹⑺⑻⑼⒈⒉⒊⒋⒌⒍⒎⒏⒐\\s]{2,4})[- ]?([0-9１２３４５６７８９０一二三四五六七八九零壹贰叁肆伍陆柒捌玖①②③④⑤⑥⑦⑧⑨㈠㈡㈢㈣㈤㈥㈦㈧㈨⑴⑵⑶⑷⑸⑹⑺⑻⑼⒈⒉⒊⒋⒌⒍⒎⒏⒐\\s]{2,4})");
    private static Pattern mobilePattern = Pattern.compile("^(13|15|18|14)[0-9]{9}$");
    private static Pattern mobileCUPattern = Pattern.compile("^(130|131|132|155|156|185|186|145)[0-9]{8}$");   //联通
    private static Pattern mobileCTPattern = Pattern.compile("^(133|153|180|189)[0-9]{8}$");   //电信
    private static Pattern contactPattern = Pattern.compile("(QQ|ＱＱ|MSN|ＭＳＮ|邮件|mail|百度)", Pattern.CASE_INSENSITIVE);
    private static Pattern urlPattern = Pattern.compile("(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]", Pattern.CASE_INSENSITIVE);
    private static Pattern urlPattern1 = Pattern.compile("[-a-zA-Z0-9+&@#/%?=~_|!:,.;]+\\.(com|cn|hk)[-a-zA-Z0-9+?&@#/%=~_|]*", Pattern.CASE_INSENSITIVE);
    private static Pattern spiderAgentPattern = Pattern.compile(".*(Baiduspider|Googlebot|Mediapartners-Google|Slurp|contentmatch|msnbot|Sosospider|sosoimagespider|YoudaoBot|YodaoBot|Sogou\\sweb|qihoobot|ichiro|ia_archiver|Yeti|bloglines|zhuaxia|spider|bot).*", Pattern.CASE_INSENSITIVE);
    private static Pattern qqEmailPattern = Pattern.compile("(\\d+)@qq.com");
    private static Pattern aidPattern = Pattern.compile("^[0-9\\-]+$");
    private static Pattern jwdPattern = Pattern.compile("^\\-?[0-9]{1,3}\\.[0-9]+$");
    private static Pattern illegalMarkPattern = Pattern.compile("(\u0007|\u001A|\u0010|\u000E|\u0011|\u0003|\u0014|\u0015|\u000F|\u0012|\u0013)");
    private static Pattern dcFilenamePattern = Pattern.compile("^[a-z_-]{2,}\\d{2,}[a-z]{0,2}\\.[a-z]{3,4}$", Pattern.CASE_INSENSITIVE);

    /**
     * Utility to remove all HTML tags
     * @param s
     * @return string
     */
    public static String removeHTMLTag(String s){
        s = (s == null)?"":s;
        String result = lineBreakPattern.matcher(s).replaceAll("");
        result = quoteMarkPattern.matcher(result).replaceAll("");
        result = commentQuotePattern.matcher(result).replaceAll("");
        result = commentQuoteContentPattern.matcher(result).replaceAll("");
        result = htmlTagPattern.matcher(result).replaceAll("");
        result = wideSpacePattern.matcher(result).replaceAll(" ");
        result = result.trim();
        return result;
    }

    /**
     * Utility to remove all HTML tags
     * @param s
     * @param length
     * @return string
     */
    public static String removeHTMLTagExceptImg(String s, int length) {
        s = (s == null)?"":s;

        // extract img tags
        Matcher matcher = saveTagImgPattern.matcher(s);
        ArrayList<String> imgs = new ArrayList<String>();
        while (matcher.find()) {
            imgs.add(matcher.group(2));
        }

        // replace img tags with placeholder tag
        String result = saveTagImgPattern.matcher(s).replaceAll("!@!");

        // shorten string
        result = StringUtils.removeHTMLTag(result);
        length = (result.length() < length || length < 0) ? result.length() : length;
        result = result.substring(0, length);

        // put img tags back
        int imgCount = 0;
        matcher = saveTagHolderPattern.matcher(result);
        while (matcher.find()) {
            imgCount++;
        }
        for (int i = 0; i < imgCount; i++) {
            String img = imgs.get(i);
            if (img.contains("ckeditor")) {
                result = result.replaceFirst("!@!", "<img" + img + ">");
            }
            else {
                result = result.replaceFirst("!@!", "");
            }
        }

        return result;
    }

    /**
     * Utility to remove all HTML link tags
     * @param s
     * @return string
     */
    public static String removeLinkTag(String s){
        s = (s == null)?"":s;
        String result = linkTagPattern1.matcher(s).replaceAll("");
        result = linkTagPattern2.matcher(result).replaceAll("");
        result = result.trim();
        return result;
    }

    /**
     * Utility to remove all HTML img tags
     * @param s
     * @return string
     */
    public static String removeImgTag(String s){
        s = (s == null)?"":s;
        String result = imgTagPattern.matcher(s).replaceAll("");
        result = result.trim();
        return result;
    }

    /**
     * Utility to remove all "hyper place link" tags
     * @param s
     * @return string
     */
    public static String removeHyperPlaceLinkTag(String s){
        s = (s == null)?"":s;
        String result = hyperPlaceLinkTagBugFixPattern1.matcher(s).replaceAll("");
        result = hyperPlaceLinkTagBugFixPattern2.matcher(result).replaceAll("");
        result = hyperPlaceLinkTagPattern.matcher(result).replaceAll("$1");
        result = result.trim();
        return result;
    }

    /**
     * Utility to remove all contact information like phone / qq / email
     * @param s
     * @return string
     */
    public static String removeContacts(String s) {
        return removeContacts(s, true);
    }

    public static String removeContacts(String s, boolean bRemoveRelatedContact){

        s = (s == null)?"":s;
        String result;
        result = emailPattern.matcher(s).replaceAll("");
        if(bRemoveRelatedContact){
            result = phonePattern.matcher(result).replaceAll("");
            result = urlPattern.matcher(result).replaceAll("");
            result = urlPattern1.matcher(result).replaceAll("");
        }
        result = contactPattern.matcher(result).replaceAll("");

        return result;
    }

    /**
     * Utility to remove all double quote marks
     * @param s
     * @return string
     */
    public static String removeQuoteMarks(String s){
        s = (s == null)?"":s;
        return quoteMarkPattern.matcher(s).replaceAll("");
    }

    /**
     * Utility to remove all line breaks
     * @param s
     * @return string
     */
    public static String removeLineBreaks(String s){
        s = (s == null)?"":s;
        return lineBreakPattern.matcher(s).replaceAll("");
    }

    /**
     * Utility to remove all spaces
     * @param s
     * @return string
     */
    public static String removeSpaces(String s) {
        s = (s == null)?"":s;
        return s.replaceAll(" ", "");
    }

        /**
     * Utility to remove some special marks
     * @param s
     * @return string
     */
    public static String removeIllegalMarks(String s){
        s = (s == null)?"":s;
        return illegalMarkPattern.matcher(s).replaceAll("");
    }

    /**
     * Utility to convert line breaks into BR tags
     * @param s
     * @return string
     */
    public static String convertBreakTags(String s){
        return lineBreakConvertPattern.matcher(s).replaceAll("<br/>");
    }

    /**
     * Utility to convert BR tags into line breaks
     * @param s
     * @return string
     */
    public static String unconvertBreakTags(String s){
        return lineBreakTagPattern.matcher(s).replaceAll("\r\n");
    }

    /**
     * Utility to check user-agent header string to determine if it's a web spider
     * @param s
     * @return boolean
     */
    public static boolean isSpider(String s) {
        if (s == null) {
            return false;
        }

        Matcher matcher = spiderAgentPattern.matcher(s);
        return matcher.matches();
    }

    /**
     * Utility to extract QQ number from email address
     * @param s
     * @return string
     */
    public static String extractQQ(String s) {
        if (s == null) {
            return null;
        }

        Matcher matcher = qqEmailPattern.matcher(s.toLowerCase());
        if (matcher.find()) {
            return matcher.group(1);
        }

        return null;
    }

    /**
     * Utility to check if a particular query param is aid
     * @param s
     * @return boolean
     */
    public static boolean isAid(String s) {
        if (s == null) {
            return false;
        }

        Matcher matcher = aidPattern.matcher(s);
        return matcher.matches();
    }

    /**
     * Utility to check if a String is valid latitude/longitude
     * @param s
     * @return boolean
     */
    public static boolean isJwd(String s) {
        if (s == null) {
            return false;
        }

        Matcher matcher = jwdPattern.matcher(s);
        return matcher.matches();
    }

    /**
     * Utility to check if a String is a digital camera filename
     * @param s
     * @return boolean
     */
    public static boolean isDCFilename(String s) {
        if (s == null) {
            return false;
        }
        
        Matcher matcher = dcFilenamePattern.matcher(s);
        return matcher.matches();
    }

    static Pattern emailer;
	/**
	 * 判断是不是一个合法的电子邮件地址
	 * @param email
	 * @return boolean
	 */
	public static boolean isEmail(String email){
        if(email == null || email.trim().length() == 0){
            return false;
        }
        if(emailer==null){
			String check = "^([a-z0-9A-Z]+[-_.~]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
			emailer = Pattern.compile(check, Pattern.CASE_INSENSITIVE);
		}
	    Matcher matcher = emailer.matcher(email);
	    return matcher.matches();
	}

	/**
	 * 判断是不是一个合法的手机号
	 * @param mobile
	 * @return boolean
	 */
	public static boolean isMobile(String mobile){
        if(mobile == null || mobile.trim().length() == 0){
            return false;
        }
	    Matcher matcher = mobilePattern.matcher(mobile);
	    return matcher.matches();
	}

    public static String getEmailByMobile(String mobile) {
        if (mobileCUPattern.matcher(mobile).matches()) {    // 联通
            return mobile + "@wo.com.cn";
        }
        else if (mobileCTPattern.matcher(mobile).matches()) {   // 电信
            return mobile + "@189.cn";
        }
        else {  // 默认：移动
            return mobile + "@139.com";
        }
    }

    public static String getMobileOperator(String mobile) {
        if (mobileCUPattern.matcher(mobile).matches()) {
            return "联通";
        }
        else if (mobileCTPattern.matcher(mobile).matches()) {
            return "电信";
        }
        else {
            return "移动";
        }
    }

    public static String readInputStream(InputStream is) {
        StringBuilder buffer = new StringBuilder();
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(is));
            String line;
            while ((line = in.readLine()) != null) {
                buffer.append(line);
            }
        }
        catch (Exception e) {
            return null;
        }
        finally {
            try {
                if (is != null) {
                    is.close();
                }
            }
            catch (Exception ie) {}
        }
        return buffer.toString();
    }

	/**
	 * 加密
	 * @param src 数据源
	 * @param key 密钥，长度必须是8的倍数
	 * @return	  返回加密后的数据
	 * @throws Exception
	 */
	public static byte[] encrypt(byte[] src, byte[] key)
		throws Exception {
		//		DES算法要求有一个可信任的随机数源
		SecureRandom sr = new SecureRandom();
		// 从原始密匙数据创建DESKeySpec对象
		DESKeySpec dks = new DESKeySpec(key);
		// 创建一个密匙工厂，然后用它把DESKeySpec转换成
		// 一个SecretKey对象
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
		SecretKey securekey = keyFactory.generateSecret(dks);
		// Cipher对象实际完成加密操作
		Cipher cipher = Cipher.getInstance(DES);
		// 用密匙初始化Cipher对象
		cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
		// 现在，获取数据并加密
		// 正式执行加密操作
		return cipher.doFinal(src);
	}

	/**
	 * 解密
	 * @param src	数据源
	 * @param key	密钥，长度必须是8的倍数
	 * @return		返回解密后的原始数据
	 * @throws Exception
	 */
	public static byte[] decrypt(byte[] src, byte[] key)
		throws Exception {
		//		DES算法要求有一个可信任的随机数源
		SecureRandom sr = new SecureRandom();
		// 从原始密匙数据创建一个DESKeySpec对象
		DESKeySpec dks = new DESKeySpec(key);
		// 创建一个密匙工厂，然后用它把DESKeySpec对象转换成
		// 一个SecretKey对象
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
		SecretKey securekey = keyFactory.generateSecret(dks);
		// Cipher对象实际完成解密操作
		Cipher cipher = Cipher.getInstance(DES);
		// 用密匙初始化Cipher对象
		cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
		// 现在，获取数据并解密
		// 正式执行解密操作
		return cipher.doFinal(src);
	}
    /**
     * 密码解密
     * @param data
     * @return string
     */
    public static String decrypt(String data){
        try {
            return new String(decrypt(hex2byte(data.getBytes()),PASSWORD_CRYPT_KEY.getBytes()));
        }catch(Exception e) {
            // do nothing
        }
        return null;
    }
    /**
     * 密码加密
     * @param password
     * @return string
     */
    public static String encrypt(String password){
        try {
            return byte2hex(encrypt(password.getBytes(),PASSWORD_CRYPT_KEY.getBytes()));
        }catch(Exception e) {
            // do nothing
        }
        return null;
    }

    /**
     * 密码MD5加密
     * @param password
     * @return string
     */
    public static String md5(String password , String charset){
        char hexDigits[] = {
                      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
                      'e', 'f'};
        try{
            byte[]   strTemp   =  null;
            if(StringUtils.isNotEmpty(charset)){
                strTemp = password.getBytes(charset);
            }else{
                strTemp = password.getBytes();
            }
            MessageDigest   mdTemp   =   MessageDigest.getInstance("MD5");
            mdTemp.update(strTemp);
            byte[] md = mdTemp.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k =  0;
            for(int i = 0; i <  j; i++){
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        }catch(Exception e){
            return   null;
        }
    }

    /**
     * 密码MD5加密
     * @param password
     * @return string
     */
    public static String  md5(String   password){
        return md5(password,null);
    }

    public static String generate_password_salt(int length)
	{
		StringBuffer salt = new StringBuffer();
        Random random = new Random();
		random.setSeed(System.currentTimeMillis() * 1000000 );

		for ( int i = 0; i < length; i++ )
		{
			int num   = random.nextInt(93) + 33;

			if ( num == 92 ){
				num = 93;
			}

			salt.append((char)num);
		}

		return salt.toString();
	}

    public static String generate_new_password(int length){
		StringBuffer pass = new StringBuffer();
        Random random = new Random();
		random.setSeed(System.currentTimeMillis() * 1000000 );

		for ( int i = 0; i < length; i++ ){
			int num   = random.nextInt(10) + 48;

			pass.append((char)num);
		}

		return pass.toString();
	}

    /**
	 * 二行制转字符串
	 * @param b
	 * @return string
	 */
    public static String byte2hex(byte[] b) {
		String hs = "";
		String stmp;
		for (int n = 0; n < b.length; n++) {
			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
		}
		return hs.toUpperCase();
	}

    public static byte[] hex2byte(byte[] b) {
        if((b.length%2)!=0)
            throw new IllegalArgumentException("长度不是偶数");
		byte[] b2 = new byte[b.length/2];
		for (int n = 0; n < b.length; n+=2) {
		    String item = new String(b,n,2);
		    b2[n/2] = (byte)Integer.parseInt(item,16);
		}
        return b2;
    }

    public static int getByteLength(String s) {
        if(s == null) {
            return 0;
        }

        int i = 0;
        for(int j = 0; j < s.length(); j++) {
            if(s.charAt(j) < '\377')
                i++;
            else
                i += 2;
        }
        return i;
    }

    /**
     * 大小写无关的字符串替换策略
     * @param str
     * @param src
     * @param obj
     * @return string
     */
    public static String replaceIgnoreCase(String str, String src, String obj){
    	String l_str = str.toLowerCase();
    	String l_src = src.toLowerCase();
    	int fromIdx = 0;
    	StringBuffer result = new StringBuffer();
    	do{
    		int idx = l_str.indexOf(l_src, fromIdx);
    		if(idx==-1)
    			break;
    		result.append(str.substring(fromIdx, idx));
    		result.append(obj);
    		fromIdx = idx + src.length();
    	}while(true);
    	result.append(str.substring(fromIdx));
    	return result.toString();
    }

    public static String extractImg(String content){
        int index = content.indexOf("<img");
        if(index != -1){
            content = content.substring(index + 4);
            index = content.indexOf("src=\"");
            if(index != -1){
                content = content.substring(index + 5);
                index = content.indexOf("\"");
                if(index != -1){
                    return content.substring(0, index);
/*
                    String img = content.substring(0, index);
                    int in = img.indexOf("/photo/");
                    if(img.startsWith("/upload/") && img.indexOf("/thumb/") < 0 && in > 0){
                        String first = img.substring(0, in + 7);
                        String last = img.substring(in + 7);
                        return first + "/thumb/" + last;

                    }else{
                        return img;
                    }
*/
                }
            }
        }
        return "";
    }

    public static String getParentid(String aid){
        String result = "0-00-00";
        if (aid != null && aid.length() >= 4) {
            if (aid.startsWith("1-01") && aid.length() >= 7) { // province
                result = aid.substring(0, 7);
            }
            else if (!aid.startsWith("1-01")) { // country
                result = aid.substring(0, 4);
            }
        }
        return result;
    }

    public static String getParentidEmpty(String aid){
        String result = getParentid(aid);
        return result.equals("0-00-00") ? "" : result;
    }

    public static String getParentids(List<String> aids){
        List<String> parentidList = new ArrayList<String>();
        for (String aid : aids) {
            String parentid = StringUtils.getParentid(aid);
            if (!parentidList.contains(parentid)) {
                parentidList.add(parentid);
            }
        }
        return StringUtils.join(parentidList, ";");
    }

    public static String getGparentid(String aid){
        String result = "0";
        if (aid != null && aid.length() >= 4) {
            if (!aid.startsWith("1-01")) { // abroad
                result = aid.substring(0, 1);
            }
        }
        return result;
    }

    public static String getGparentidEmpty(String aid){
        String result = getGparentid(aid);
        return result.equals("0") ? "" : result;
    }

    public static String getGparentids(List<String> aids){
        List<String> gparentidList = new ArrayList<String>();
        for (String aid : aids) {
            String gparentid = StringUtils.getGparentid(aid);
            if (!gparentidList.contains(gparentid)) {
                gparentidList.add(gparentid);
            }
        }
        return StringUtils.join(gparentidList, ";");
    }

    public static int getHashBucket(String src, int mod) {
        String md5Str = md5(src);
        int srcValue = Integer.parseInt(md5Str.substring(0, 3), 16);
        return srcValue % mod;
    }

    private static final char[] hexDigit = {
         '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
    };

    private static char toHex(int nibble) {
         return hexDigit[(nibble & 0xF)];
    }

    /**
     * 将字符串编码成 Unicode 。
     * @param theString 待转换成Unicode编码的字符串。
     * @param escapeSpace 是否忽略空格。
     * @return 返回转换后Unicode编码的字符串。
     */
    public static String toUnicode(String theString, boolean escapeSpace) {
        int len = theString.length();
        int bufLen = len * 2;
        if (bufLen < 0) {
            bufLen = Integer.MAX_VALUE;
        }
        StringBuffer outBuffer = new StringBuffer(bufLen);

        for(int x=0; x<len; x++) {
            char aChar = theString.charAt(x);
            // Handle common case first, selecting largest block that
            // avoids the specials below
            if ((aChar > 61) && (aChar < 127)) {
                if (aChar == '\\') {
                    outBuffer.append('\\'); outBuffer.append('\\');
                    continue;
                }
                outBuffer.append(aChar);
                continue;
            }
            switch(aChar) {
                case ' ':
                    if (x == 0 || escapeSpace)
                        outBuffer.append('\\');
                    outBuffer.append(' ');
                    break;
                case '\t':outBuffer.append('\\'); outBuffer.append('t');
                          break;
                case '\n':outBuffer.append('\\'); outBuffer.append('n');
                          break;
                case '\r':outBuffer.append('\\'); outBuffer.append('r');
                          break;
                case '\f':outBuffer.append('\\'); outBuffer.append('f');
                          break;
                case '=': // Fall through
                case ':': // Fall through
                case '#': // Fall through
                case '!':
                    outBuffer.append('\\'); outBuffer.append(aChar);
                    break;
                default:
                    if ((aChar < 0x0020) || (aChar > 0x007e)) {
                        outBuffer.append('\\');
                        outBuffer.append('u');
                        outBuffer.append(toHex((aChar >> 12) & 0xF));
                        outBuffer.append(toHex((aChar >>  8) & 0xF));
                        outBuffer.append(toHex((aChar >>  4) & 0xF));
                        outBuffer.append(toHex( aChar        & 0xF));
                    } else {
                        outBuffer.append(aChar);
                    }
            }
        }
        return outBuffer.toString();
    }

    //转化字符串为十六进制编码
    public static String toHexString(String s){
       String str="";
       for (int i=0;i<s.length();i++)
       {
        int ch = (int)s.charAt(i);
        String s4 = Integer.toHexString(ch);
        str = str + s4;
       }
        return str;//0x表示十六进制
    }

    //转换十六进制编码为字符串
    public static String toStringHex(String s)
    {
       if("0x".equals(s.substring(0, 2)))
       {
        s =s.substring(2);
       }
       byte[] baKeyword = new byte[s.length()/2];
       for(int i = 0; i < baKeyword.length; i++)
       {
          try
          {
           baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i*2, i*2+2),16));
          }
          catch(Exception e)
          {
           e.printStackTrace();
          }
       }

       try
       {
        s = new String(baKeyword, "utf-8");//UTF-16le:Not
       }
       catch (Exception e1)
       {
        e1.printStackTrace();
       }
       return s;
    }
    public static String bytesToHexString(byte[] src){
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * 从 Unicode 码转换成编码前的特殊字符串。
     * @param in Unicode编码的字符数组。
     * @return 完成转换，返回编码前的特殊字符串。
     */
    public static String fromUnicode(char[] in) {
       int newLen = in.length * 2;
       if (newLen < 0) {
           newLen = Integer.MAX_VALUE;
       }


        char aChar;
        char[] out = new char[in.length];
        int outLen = 0;
        int off = 0;

        while (off < in.length) {
            aChar = in[off++];
            if (aChar == '\\') {
                aChar = in[off++];
                if (aChar == 'u') {
                    // Read the xxxx
                    int value = 0;
                    for (int i = 0; i < 4; i++) {
                        aChar = in[off++];
                        switch (aChar) {
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                        case '8':
                        case '9':
                            value = (value << 4) + aChar - '0';
                            break;
                        case 'a':
                        case 'b':
                        case 'c':
                        case 'd':
                        case 'e':
                        case 'f':
                            value = (value << 4) + 10 + aChar - 'a';
                            break;
                        case 'A':
                        case 'B':
                        case 'C':
                        case 'D':
                        case 'E':
                        case 'F':
                            value = (value << 4) + 10 + aChar - 'A';
                            break;
                        default:
                            throw new IllegalArgumentException(
                                    "Malformed \\uxxxx encoding.");
                        }
                    }
                    out[outLen++] = (char) value;
                } else {
                    if (aChar == 't') {
                        aChar = '\t';
                    } else if (aChar == 'r') {
                        aChar = '\r';
                    } else if (aChar == 'n') {
                        aChar = '\n';
                    } else if (aChar == 'f') {
                        aChar = '\f';
                    }
                    out[outLen++] = aChar;
                }
            } else {
                out[outLen++] = (char) aChar;
            }
        }
        return new String(out, 0, outLen);
    }

    public static String encodeURL(String baseURL){
        String encodeURL = "";
        try{
            if(StringUtils.isNotEmpty(baseURL)){
                ScriptEngineManager factory = new ScriptEngineManager();
                ScriptEngine engine = factory.getEngineByName("JavaScript");
                encodeURL = engine.eval("encodeURI('" + baseURL + "')").toString();
            }
        }catch(Exception e){}

        return encodeURL;
    }
    
    /**
     * 格式数字类型
     * @param f
     * @param pattern
     * @return
     */
    public static String formatNumber(double f, String pattern) {  
        java.text.DecimalFormat num = new DecimalFormat(pattern);  
        return num.format(f);  
    }  
    
    /**
     * null对象转换成空字符串
     * @param obj
     * @return
     */
    public static String null2Blank(Object obj) {
        return (obj == null) ? "" : obj.toString();
    }
    
    public static String getSubLengthString(String str, int length) {
        if(str != null && str.length() > length) {
            return str.substring(0, length -1);
        }
        return  str;
    }

    public static void main(String[] argvs) throws Exception {
    /*
        String test = "<div class=\"quote-box\">\n" +
                      "<div class=\"hide\">=============================================================================</div>\n" +
                      "<div class=\"quote-content\"><strong>引用:</strong> <em>原帖由 <a target=\"_blank\" href=\"/user/01145483F4B7046AFF8080811451839E\">自由老驴王</a> 于 2007-11-22 13:50 发表</em><br />\n" +
                      "填表时，性别那一栏，老是想这&ldquo;男&rdquo;字太&ldquo;农业大国&rdquo;化了。不就是&ldquo;庄家地里的长工&rdquo;吗？哈哈。嘿嘿，还没看出来能不能&ldquo;逃&rdquo;哟？还是&ldquo;逃&rdquo;一回为好。哈哈</div>\n" +
                      "</div>\n" +
                      "<div class=\"hide\">=============================================================================</div>\n" +
                      "<br />\n" +
                      "据说&ldquo;田&rdquo;的含义不同了，是&ldquo;四口&rdquo;－车子、房子、孩子、婆子，都需要男人用力自己顶着，反而吧爹妈给忘了！";
        String xxx = StringUtils.removeHTMLTag(test);
        String test = "2008年8月炎热的夏季，加上奥运的热潮，驱使我非常想到北方避一避暑气，于是心血来潮于12日乘火车一路向北进发，经过一夜的颠簸于第二天中午到<a href=\"http://www.yododo.com/area/1-01-11-16-01\" target=\"_blank\" class=\"hyper\" rev=\"1-01-11-16-01\" title=\"齐齐哈尔自助游\">齐齐哈尔</a>站稍事休息又称夜车直奔边境小镇<a href=\"http://www.yododo.com/area/1-01-18-24-01\" target=\"_blank\" class=\"hyper\" rev=\"1-01-18-24-01\" title=\"满洲里自助游\">满洲里</a>。第二天清晨就到了。<br />";
        String xxx = StringUtils.removeLinkTag(test);
*/
        String test = "<div class=\"quote-box\">\n" +
                      "<div class=\"hide\">=============================================================================</div>\n" +
                      "<div class=\"quote-content\"><strong>引用:</strong> <em>原帖由 <a target=\"_blank\" href=\"/user/01145483F4B7046AFF8080811451839E\">自由老驴王</a> 于 2007-11-22 13:50 发表</em><br />\n" +
                      "填表时，性别那一栏，老是想这&ldquo;男&rdquo;字太&ldquo;农业大国&rdquo;化了。不就是&ldquo;庄家地里的长工&rdquo;吗？哈哈。嘿嘿，还没看出来能不能&ldquo;逃&rdquo;哟？还是&ldquo;逃&rdquo;一回为好。哈哈</div>\n" +
                      "</div>\n" +
                      "<div class=\"hide\">=============================================================================</div>\n" +
                      "<br />\n" +
                      "据说&ldquo;田&rdquo;的含义不同了，<img alt=\"呲牙\" src=\"http://img0.yododo.com/ckeditor/plugins/smiley/images/qq/teeth.gif\" title=\"呲牙\" />是&ldquo;四口&rdquo;－车子、房子、孩子、婆子，都需要男人用力自己顶着，反而吧爹妈给忘了！<img alt=\"呲牙\" src=\"http://img0.yododo.com/ckeditor/plugins/smiley/images/qq/teeth.gif\" title=\"呲牙\" />";
        String xxx = StringUtils.removeHTMLTagExceptImg(test, 52);
        System.err.println(xxx);

/*
        String test = "<font face=\"Verdana\"><font color=\"#0066ff\">第五天：<a class=\"hyper\" title=\"香格里拉自助游\" target=\"_blank\" rev=\"1-01-29-56-01\" href=\"http://www.yododo.com/area/1-01-29-56-01\">香<span style=\"color: #008080\"><strong>格里</strong></span><span style=\"color: #ff0000\">拉</span></a><span style=\"color: #ff0000\">乡/</span><a class=\"hyper\" title=\"新都桥自助游\" target=\"_blank\" rev=\"1-01-25-20-03\" href=\"http://www.yododo.com/area/1-01-25-20-03\"><span style=\"color: #ff0000\">新都</span>桥</a>&nbsp;&nbsp;&nbsp; &nbsp; </font></font><font face=\"Verdana\"><font color=\"#0066ff\">住：<a class=\"hyper\" title=\"新都桥自助游\" target=\"_blank\" rev=\"1-01-25-20-03\" href=\"http://www.yododo.com/area/1-01-25-20-03\">新都桥</a>鑫泰酒店（当地最好酒店之一）或同级</font></font><br />";
        String xxx = StringUtils.removeHyperPlaceLinkTag(test);
        System.out.println(xxx);
*/
/*
        String test1 = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; User-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; http://bsalsa.com) ; .NET CLR 1.1.4322; .NET CLR 2.0.50727; WWTClient2)";
        String test2 = null;
        String test3 = "Mediapartners-Google";
        String test4 = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)";
        String test5 = "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)";
        String test6 = "Mozilla/5.0 (compatible; Yahoo ContentMatch Crawler/2.1; FreeBSD; http://p4p.cn.yahoo.com/)";
        String test7 = "Baiduspider+(+http://www.baidu.com/search/spider.htm)";
        System.err.println(StringUtils.isSpider(test1));
        System.err.println(StringUtils.isSpider(test2));
        System.err.println(StringUtils.isSpider(test3));
        System.err.println(StringUtils.isSpider(test4));
        System.err.println(StringUtils.isSpider(test5));
        System.err.println(StringUtils.isSpider(test6));
        System.err.println(StringUtils.isSpider(test7));
*/
/*
        System.err.println(StringUtils.getHashBucket("icon_images.gif", 4));
        System.err.println(StringUtils.getHashBucket("icon_good.gif", 4));
        System.err.println(StringUtils.getHashBucket("icon_bad.gif", 4));
*/

        Pattern testPattern = Pattern.compile("^(?!org\\.apache\\.catalina\\.valves\\.CrawlerSessionManagerValve).*");
        System.err.println(testPattern.matcher("user").matches());
        System.err.println(testPattern.matcher("").matches());
        System.err.println(testPattern.matcher("org.apache.catalina.valves.CrawlerSessionManagerValve").matches());
        System.err.println(testPattern.matcher("xorg.apache.catalina.valves.CrawlerSessionManagerValve").matches());
        System.err.println(testPattern.matcher("orgxapache.catalina.valves.CrawlerSessionManagerValve").matches());
        System.err.println(testPattern.matcher("CrawlerSessionManagerValve").matches());
    }
}
